<template>
	<view class="container">
		<!-- 定位 -->
		<view class="location" @click="chooseLocation()">
			<u-icon name="map-fill" color="#018d71" size="36"></u-icon>
			<text class="address">{{ location || '点击获取定位' }}</text>
		</view>

		<!-- 搜索框 -->
		<view class="search-box">
			<view class="search-input">
				<u-icon name="search" size="40" color="#666"></u-icon>
				<input type="text" v-model="keyword" placeholder="搜索商品" placeholder-class="placeholder"
					@confirm="search" />
			</view>
		</view>

		<!-- 主体内容 -->
		<view class="main">
			<!-- 左侧分类导航 -->
			<scroll-view class="category-nav" scroll-y>
				<view class="nav-item" v-for="(category, index) in Object.keys(categoryMap)" :key="index"
					:class="{ active: currentCategory === category }" @click="changeCategory(category)">
					<text class="text">{{ category }}</text>
				</view>
			</scroll-view>

			<!-- 右侧商品列表 -->
			<scroll-view class="goods-list" scroll-y @scrolltolower="loadMore">
				<!-- 搜索结果提示 -->
				<view class="search-result" v-if="keyword">
					<view class="title">
						<text>搜索 {{keyword}}</text>
						<text class="count">共 {{goodsList.length}} 个结果</text>
					</view>
					<view class="clear" @tap="clearSearch">
						<u-icon name="close" size="24" color="#999"></u-icon>
						<text>清除搜索</text>
					</view>
				</view>

				<view class="goods-grid">
					<view class="goods-item" v-for="(item, index) in showList" :key="index" @click="navToDetail(item)">
						<view class="goods-img">
							<image :src="item.cover" mode="aspectFill"></image>
						</view>
						<view class="info">
							<view class="name">{{ item.name }}</view>
							<view class="price">
								<text class="symbol">¥</text>
								<text class="number">{{item.price}}</text>
								<text class="sales">已售 {{item.sales}} 件</text>
							</view>
						</view>
					</view>
				</view>

				<!-- 加载状态 -->
				<view class="loading-more" v-if="loading">
					<u-loading mode="circle"></u-loading>
					<text>加载中...</text>
				</view>

				<!-- 无数据提示 -->
				<view class="no-data" v-if="showList.length === 0">
					<u-empty mode="data"></u-empty>
				</view>
			</scroll-view>
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				configDistance: 0,
				location: '',
				shopLocation: {},
				keyword: '',
				categoryMap: {},
				currentCategory: '',
				page: 1,
				pageSize: 10,
				loading: false,
				goodsList: [], // 搜索结果列表
				hasMore: true // 是否还有更多数据
			}
		},
		computed: {
			showList() {
				// 如果有搜索关键词，显示搜索结果，否则显示分类商品
				return this.keyword ? this.goodsList : (this.categoryMap[this.currentCategory] || [])
			}
		},
		onLoad() {
			this.getConfig();
			if (this.location == '') {
				uni.showModal({
					title: '提示',
					content: '获取定位确定是否在配送范围',
					success: (res) => {
						if (res.confirm) {
							this.chooseLocation()
						}
					}
				})
			}
		},
		onShow() {
			this.loadCategories();
		},
		// 分享设置
		onShareAppMessage() {
			return {
				title: '优质包装材料',
				path: '/pages/goods/list',
				imageUrl: '/static/share.png'
			}
		},
		// 分享到朋友圈
		onShareTimeline() {
			return {
				title: '优质包装材料',
				imageUrl: '/static/share.png'
			}
		},
		methods: {
			// 选择地址
			chooseLocation() {
				uni.chooseLocation({
					success: (res) => {
						// 检查配送范围
						const {
							inRange,
							distance
						} = this.checkDeliveryRange(res.latitude, res.longitude)

						if (!inRange) {
							uni.showModal({
								title: '超出配送范围',
								content: `该地址距离门店${(distance/1000).toFixed(1)}公里，超出配送范围(${this.configDistance}公里)`,
								showCancel: false
							})
							return
						}

						// 保存地址信息
						this.location = res.address
					},
					fail: (err) => {
						console.log(err);
						if (err.errMsg.indexOf('auth deny') !== -1) {
							uni.showModal({
								title: '提示',
								content: '请在系统设置中打开定位权限',
								showCancel: false
							})
						} else {
							uni.showToast({
								title: '选择地址失败',
								icon: 'none'
							})
						}

					}
				})
			}, // 检查配送范围
			checkDeliveryRange(latitude, longitude) {
				const distance = this.calculateDistance(
					latitude,
					longitude,
					this.shopLocation.latitude,
					this.shopLocation.longitude
				)
				return {
					inRange: distance <= this.configDistance * 1000, // 
					distance: Math.round(distance)
				}
			},
			getConfig() {
				vk.callFunction({
					url: 'client/system/pub/config',
					success: (data) => {
						if (data.item) {
							this.shopLocation = data.item.shopLocation
							this.configDistance = data.item.deliver_distance
						}
					}
				})
			},
			// 计算两点之间的距离(单位:米)
			calculateDistance(lat1, lon1, lat2, lon2) {
				const R = 6371000 // 地球半径(米)
				const dLat = this.deg2rad(lat2 - lat1)
				const dLon = this.deg2rad(lon2 - lon1)
				const a = 
					Math.sin(dLat/2) * Math.sin(dLat/2) +
					Math.cos(this.deg2rad(lat1)) * Math.cos(this.deg2rad(lat2)) * 
					Math.sin(dLon/2) * Math.sin(dLon/2)
				const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a))
				return R * c
			},
			// 角度转弧度
			deg2rad(deg) {
				return deg * (Math.PI/180)
			},
			// 加载分类和商品
			loadCategories() {
				vk.callFunction({
					url: 'client/goods/pub/category',
					title: '请求中...',
					success: (data) => {
						this.categoryMap = data.data.categoryGoodsMap;
						if (!this.currentCategory) {
							this.currentCategory = Object.keys(this.categoryMap)[0];
						}
					}
				});
			},
			// 切换分类
			changeCategory(category) {
				this.currentCategory = category;
				this.page = 1;
			},
			// 搜索商品
			search() {
				if (!this.keyword.trim()) return
				this.page = 1
				this.hasMore = true
				this.goodsList = []
				this.loadSearchResult()
			},
			// 加载搜索结果
			loadSearchResult() {
				if (!this.hasMore || this.loading) return

				this.loading = true
				vk.callFunction({
					url: 'client/goods/pub/search',
					title: '请求中...',
					data: {
						value: this.keyword,
						page: this.page,
						pageSize: this.pageSize
					},
					success: (data) => {
						const {
							rows,
							total
						} = data
						if (this.page === 1) {
							this.goodsList = rows
						} else {
							this.goodsList = [...this.goodsList, ...rows]
						}
						this.hasMore = this.goodsList.length < total
					},
					complete: () => {
						this.loading = false
					}
				});
			},
			// 清除搜索
			clearSearch() {
				this.keyword = ''
				this.goodsList = []
				this.page = 1
				this.hasMore = true
			},
			// 加载更多
			loadMore() {
				if (this.keyword) {
					// 搜索模式下加载更多
					if (this.hasMore) {
						this.page++
						this.loadSearchResult()
					}
				}
			},
			// 跳转到商品详情
			navToDetail(goods) {
				uni.navigateTo({
					url: `/pages/goods/detail?id=${goods._id}`
				});
			}
		}
	}
</script>

<style lang="scss" scoped>
	@mixin text-ellipsis($line: 1) {
		@if $line ==1 {
			overflow: hidden;
			text-overflow: ellipsis;
			white-space: nowrap;
		}

		@else {
			overflow: hidden;
			text-overflow: ellipsis;
			display: -webkit-box;
			-webkit-line-clamp: $line;
			-webkit-box-orient: vertical;
		}
	}

	.container {
		height: 100vh;
		display: flex;
		flex-direction: column;

		.location {
			display: flex;
			align-items: center;
			padding: 20rpx 30rpx;
			background-color: #fff;

			.address {
				flex: 1;
				margin: 0 20rpx;
				font-size: 28rpx;
				color: #333;
			}
		}

		.search-box {
			padding: 20rpx;
			background-color: #fff;
			border-bottom: 1rpx solid #f5f5f5;

			.search-input {
				display: flex;
				align-items: center;
				height: 70rpx;
				padding: 0 30rpx;
				background-color: #f5f5f5;
				border-radius: 35rpx;

				input {
					flex: 1;
					margin-left: 20rpx;
					font-size: 28rpx;
					color: #333;

					&.placeholder {
						color: #999;
					}
				}
			}
		}

		.main {
			flex: 1;
			display: flex;
			overflow: hidden;

			.category-nav {
				width: 180rpx;
				background-color: #f8f8f8;

				.nav-item {
					height: 90rpx;
					display: flex;
					align-items: center;
					justify-content: center;
					text-align: center;
					font-size: 28rpx;
					color: #333;
					position: relative;

					.text {
						padding: 0 20rpx;
						@include text-ellipsis(1);
					}

					&.active {
						background-color: #fff;
						color: #018d71;
						font-weight: bold;

						&:before {
							content: '';
							position: absolute;
							left: 0;
							top: 50%;
							transform: translateY(-50%);
							width: 8rpx;
							height: 32rpx;
							background-color: #018d71;
							border-radius: 0 4rpx 4rpx 0;
						}
					}
				}
			}

			.goods-list {
				flex: 1;
				background-color: #fff;

				.goods-grid {
					display: grid;
					grid-template-columns: repeat(2, 1fr);
					padding: 24rpx 20rpx;
					grid-gap: 20rpx;

					.goods-item {
						background-color: #fff;
						border-radius: 12rpx;
						overflow: hidden;
						box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.06);
						border: 2rpx solid #f5f5f5;

						.goods-img {
							width: 100%;
							height: 260rpx;
							overflow: hidden;

							image {
								width: 100%;
								height: 100%;
								transition: transform 0.3s;
							}
						}

						&:active {
							.goods-img image {
								transform: scale(1.05);
							}
						}

						.info {
							padding: 20rpx 16rpx;

							.name {
								font-size: 28rpx;
								color: #333;
								line-height: 1.4;
								height: 76rpx;
								@include text-ellipsis(2);
							}

							.price {
								margin-top: 16rpx;
								display: flex;
								align-items: baseline;

								.symbol {
									font-size: 24rpx;
									color: #f56c6c;
								}

								.number {
									font-size: 32rpx;
									color: #f56c6c;
									font-weight: bold;
									margin-right: 12rpx;
								}

								.sales {
									flex: 1;
									font-size: 24rpx;
									color: #999;
									text-align: right;
								}
							}
						}
					}
				}
			}
		}

		.search-result {
			display: flex;
			justify-content: space-between;
			align-items: center;
			padding: 20rpx 30rpx;
			background: #fff;
			margin-bottom: 20rpx;

			.title {
				font-size: 28rpx;
				color: #333;

				.count {
					font-size: 24rpx;
					color: #999;
					margin-left: 10rpx;
				}
			}

			.clear {
				display: flex;
				align-items: center;
				font-size: 24rpx;
				color: #999;

				text {
					margin-left: 6rpx;
				}
			}
		}

		.loading-more {
			display: flex;
			align-items: center;
			justify-content: center;
			padding: 30rpx 0;

			text {
				font-size: 24rpx;
				color: #999;
				margin-left: 10rpx;
			}
		}

		.no-data {
			display: flex;
			justify-content: center;
			align-items: center;
			padding: 30rpx 0;
		}
	}
</style>